package com.gtmc.gclub.chat.aop;

import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 日志记录
 * 
 * @author BENJAMIN
 *
 */
@Order(1)
@Aspect
@Component
public class LogMonitor {

	private Logger logger = LoggerFactory.getLogger(LogMonitor.class);

	@Autowired
	private HttpServletRequest request;

	@Before("execution(* com.gtmc.gclub.chat.controller.*Controller.*(..))")
	public void beforeLog(JoinPoint point) {
		try {
			logger.info("------beforeLog------");
			String beanName = point.getSignature().getDeclaringTypeName();
			String methodName = point.getSignature().getName();
			String uri = request.getRequestURI();
			if ("/chat/file".equals(uri)) {
				logger.info("------endLog------");
				return;
			}
			String remoteAddr = getIpAddr(request);
			String method = request.getMethod();
			String params = "";
			String localAddr = InetAddress.getLocalHost().getHostAddress();
			// if ("POST".equals(method)) {
			StringBuffer str = new StringBuffer();
			Object[] paramsArray = point.getArgs();
			for (int i = 0; i < paramsArray.length; i++) {
				str.append(beanToString(paramsArray[i])).append(";");
			}
			params = str.toString();
			// } else {
			// Map<?, ?> paramsMap = (Map<?, ?>)
			// request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
			// params = paramsMap.toString();
			// }
			String content = "uri=" + uri + ";\r\n" + "beanName=" + beanName + ";\r\n" + "remoteAddr=" + remoteAddr
					+ ";\r\n" + "methodName=" + methodName + ";\r\n" + "params=" + params;
			// 数据库取序列
			logger.info("error:" + content);
			logger.info("------endLog------");
		} catch (Exception e) {
			logger.error("***操作输入日志记录失败beforeLog()***", e);
		}
	}

	@AfterReturning(pointcut = "execution(* com.gtmc.gclub.chat.controller.*Controller.*(..))", returning = "result")
	public void doAfterReturning(Object result) {
		logger.info("------afterLog------");
		try {
			String resultData = beanToString(result);
			logger.info("result:" + resultData);
			logger.info("------afterLog------end");
		} catch (Exception e) {
			logger.error("***操作输出日志记录失败doAfterReturning()***", e);
		}
	}

	/**
	 * 获取登录用户远程主机ip地址
	 * 
	 * @param request
	 * @return
	 */
	private String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 请求参数拼装
	 * 
	 * @param paramsArray
	 * @return
	 * @throws JsonProcessingException
	 */
	private String beanToString(Object paramsArray) {
		String params = "";
		try {
			ObjectMapper mapper = new ObjectMapper();
			params = mapper.writeValueAsString(paramsArray);
		} catch (Exception e) {
			logger.error("解析aop参数错误! 可忽略", e);
		}
		return params.trim();
	}

	public String getCurrentDate() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMDD");
		return sdf.format(new Date());
	}

}
